package com.tangyuan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tangyuan.common.util.RedisUtil;
import com.tangyuan.mapper.MovieCoordinationMapper;
import com.tangyuan.model.MovieCoordination;
import com.tangyuan.model.UserAction;
import com.tangyuan.recommend.BashRecommend;
import com.tangyuan.service.MovieCoordinationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 小梁
 * @since 2020-12-03
 */
@Slf4j
@Service
public class MovieCoordinationServiceImpl extends ServiceImpl<MovieCoordinationMapper, MovieCoordination> implements MovieCoordinationService {

    @Autowired
    MovieCoordinationMapper movieCoordinationMapper;

    @Autowired
    BashRecommend bashRecommend;
    @Autowired
    RedisUtil redisUtil;

    @Override
    public void saveMovieCoordination(List<UserAction> userActions) {
        long l = System.currentTimeMillis();
        if(CollectionUtils.isEmpty(userActions)){
            return;
        }
        //昨日观看记录
        Map<Long, Integer> map = userActions.stream()
                .collect(Collectors.groupingBy(UserAction::getMovieId,
                        Collectors.collectingAndThen(Collectors.counting(), Long::intValue)));
        //数据库中存在数据
        List<MovieCoordination> movieCoordinationList = getCoordinationByMovieId(new ArrayList<>(map.keySet()));
        Map<Long, MovieCoordination> dataMap = movieCoordinationList.stream().collect(Collectors.toMap(MovieCoordination::getMovieId,movie -> movie));
        //需要保存的数据
        List<MovieCoordination> saveMovieCoordination = new ArrayList<>();
        //遍历昨日观看记录
        for (Long aLong : map.keySet()) {
            MovieCoordination coordination = dataMap.get(aLong);
            //数据中没有改对应数据
            if(coordination == null){
                coordination = new MovieCoordination();
                coordination.setMovieId(aLong);
                coordination.setDistance(1);
            }else {
                coordination.setDistance(coordination.getDistance() + map.get(aLong));
            }
            saveMovieCoordination.add(coordination);
        }
        this.saveOrUpdateBatch(saveMovieCoordination);
        log.info("saveMovieCoordination:执行时间"+(System.currentTimeMillis() - l));
    }

    @Override
    public List<MovieCoordination> getCoordinationByMovieId(List<Long> movieIds) {
        if(CollectionUtils.isEmpty(movieIds)){
            return new ArrayList<>();
        }
        return baseMapper.selectList(new LambdaQueryWrapper<MovieCoordination>().in(MovieCoordination::getMovieId,movieIds));
    }

    @Override
    public List<Long> getMaxDistance(Long userId) {
        String key = Long.toString(userId);
        List<Object> objects = redisUtil.lGet(key, 0, -1);
        List<Long> list = new ArrayList<>();
        for (Object object : objects) {
            list.add(Long.valueOf(String.valueOf(object)));
        }
        QueryWrapper<MovieCoordination> wrapper = new QueryWrapper<>();
        wrapper.select("movie_id").in("movie_id", list).orderByDesc("distance");
        List<MovieCoordination> moviesList = baseMapper.selectList(wrapper);
        List<Long> movies = new ArrayList<>();
        for (MovieCoordination coordination : moviesList) {
            movies.add(coordination.getMovieId());
        }
        return bashRecommend.getRecommendMovieIdList(userId, movies); //去重
    }
}
